﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ESRI.ArcGIS.Client.Tasks;

namespace ESRI.ArcGIS.Client.Async
{
    public static partial class ArcGISImageServiceLayerExtensions
    {
        /// <summary>
        /// Adds the rasters.
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="addParameters">The add parameters.</param>
        /// <returns></returns>
        public static Task<ImageServiceEditResults> AddRastersTaskAsync(this ArcGISImageServiceLayer layer, ImageServiceAddParameters addParameters)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<ImageServiceAddParameters, ImageServiceEditResults>(layer.AddRasters, addParameters);
        }

        /// <summary>
        /// Deletes the rasters.
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="rasterIDs">The raster IDs.</param>
        /// <returns></returns>
        public static Task<ImageServiceEditResults> DeleteRastersTaskAsync(this ArcGISImageServiceLayer layer, IEnumerable<int> rasterIDs)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<IEnumerable<int>, ImageServiceEditResults>(layer.DeleteRasters, rasterIDs);
        }

        /// <summary>
        /// Asynchronous task to get the colormap information associated with the <see cref="T:ESRI.ArcGIS.Client.ArcGISImageServiceLayer"/>.
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public static Task<ColorMapTaskResult> GetColorMapTaskAsync(this ArcGISImageServiceLayer layer)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            var tcs = new TaskCompletionSource<ColorMapTaskResult>();
            layer.GetColorMapAsync((result, userToken) =>
            {
                if (result.Error != null)
                {
                    tcs.SetException(result.Error);
                }
                else
                {
                    tcs.SetResult(new ColorMapTaskResult(result.ColorMap));
                }
            });
            return tcs.Task;
        }

        /// <summary>
        /// Asynchronous task to get the histograms information associated with the <see cref="T:ESRI.ArcGIS.Client.ArcGISImageServiceLayer"/>.
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public static Task<HistogramsTaskResult> GetHistogramsTaskAsync(this ArcGISImageServiceLayer layer)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            var tcs = new TaskCompletionSource<HistogramsTaskResult>();
            layer.GetHistogramsAsync((result, userToken) =>
            {
                if (result.Error != null)
                {
                    tcs.SetException(result.Error);
                }
                else
                {
                    tcs.SetResult(new HistogramsTaskResult(result.Histograms));
                }
            });
            return tcs.Task;
        }

        /// <summary>
        /// Gets the raster attribute table resource, which returns categorical mapping of pixel values (e.g. a class, group, category, or membership).
        /// This resource is supported if hasRasterAttributeTable property of the service is true.
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public static Task<FeatureSet> GetRasterAttributeTableTaskAsync(this ArcGISImageServiceLayer layer)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<FeatureSet>(layer.GetRasterAttributeTable);
        }

        /// <summary>
        /// Gets the raster catalog items.
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="query">The query.</param>
        /// <returns></returns>
        public static Task<FeatureSet> GetRasterCatalogItemsTaskAsync(this ArcGISImageServiceLayer layer, Query query)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<Query, FeatureSet>(layer.GetRasterCatalogItems, query);
        }

        /// <summary>
        /// Gets the raster information (such as its width, height, number of bands, pixel type, etc)
        /// This resource is supported if Catalog Capability is true.
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="rasterID">The raster ID.</param>
        /// <returns></returns>
        public static Task<RasterInfo> GetRasterInfoTaskAsync(this ArcGISImageServiceLayer layer, int rasterID)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<int, RasterInfo>(layer.GetRasterInfo, rasterID);
        }

        /// <summary>
        /// Gets the raster key properties.
        /// This resource is supported if Image and Catalog Capability is true.
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="rasterID">The raster ID.</param>
        /// <returns></returns>
        public static Task<IDictionary<string, object>> GetRasterKeyPropertiesTaskAsync(this ArcGISImageServiceLayer layer, int rasterID)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<int, IDictionary<string, object>>(layer.GetRasterKeyProperties, rasterID);
        }

        /// <summary>
        /// Gets the raster metadata.
        /// This resource is supported if Image and Metadata Capability is true.
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="rasterID">The raster ID.</param>
        /// <returns></returns>
        public static Task<string> GetRasterMetadataTaskAsync(this ArcGISImageServiceLayer layer, int rasterID)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<int, string>(layer.GetRasterMetadata, rasterID);
        }

        /// <summary>
        /// Gets the service key properties.
        /// This resource is supported if Image is true.
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public static Task<IDictionary<string, object>> GetRasterMetadataTaskAsync(this ArcGISImageServiceLayer layer)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<IDictionary<string, object>>(layer.GetServiceKeyProperties);
        }

        /// <summary>
        /// Updates the raster.
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="updateParameters">The update parameters.</param>
        /// <returns></returns>
        public static Task<ImageServiceEditResults> UpdateRasterTaskAsync(this ArcGISImageServiceLayer layer, ImageServiceUpdateParameters updateParameters)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            return TaskServices.HandleActionWithCallbackArgument<ImageServiceUpdateParameters, ImageServiceEditResults>(layer.UpdateRaster, updateParameters);
        }
    }
}